
//
// 110402 - AH - (Zen) Created.
// 110403 - AH - addNode(Node).
// 110404 - AH - (Fotballpuben *) toString().
// 110410 - AH - Made iterable over nodes.
// 110625 - AH - (Fotballpuben *) hasContent(String, String).
// 110925 - AH - (Garage *) Removed debug printout.
// 110927 - AH - hasNoteContent(String, String).
//

package org.soekrat.engine.pit;

import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * <p>
 *   Pit is where
 *   {@link Node}s are living and are very happy and do not really care to
 *   much about the ontologies, in other words they are Knuts...
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class Pit implements Iterable<Node>
{
  private final Map<String, Node> m_nodes=new HashMap<String, Node>();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public Pit(){}
  
  /**
   * <p>
   *   Gets 
   *   {@link Node}.
   * </p>
   * @param name Name of node.
   * @return {@link Node}.
   */
  public Node getNode(String name)
  {
    if (name==null)
    {
      throw new NullPointerException("name");
    }
    
    Node retVal=m_nodes.get(name);
    if (retVal==null)
    {
      retVal=new Node(name);
      m_nodes.put(name, retVal);
    }
    
    return retVal;
  }
  
  /**
   * <p>
   *   Adds 
   *   {@link Node}.
   * </p>
   * @param node {@link Node} to add.
   * @return {@code false} if duplicate else if OK {@code true}.
   */
  public boolean addNode(Node node)
  {
    if (node==null)
    {
      throw new NullPointerException("node");
    }
    
    String name=node.getName();
    Node n=m_nodes.get(name);
    if (n==node) return true;
    if (n!=null)
    {
      return false;
    }
    
    m_nodes.put(name, node);
    return true;
  }
  
  /**
   * <p>
   *   Tells if has content for named
   *   {@link Node}.
   * </p>
   * @param name     {@link Node}'s name.
   * @param ontology Name on ontology to check for, if {@code null} checks if
   *                 has content defined over all ontologies.
   * @return {@code true} if has, {@code false} if has not.
   */
  public boolean hasContent(String name, String ontology)
  {
    if (name==null)
    {
      throw new NullPointerException("name");
    }
    
    Node node=getNode(name);
    if (node!=null)
    {
      Content[] content=(ontology==null) ? node.getContent() :
                                           node.getContent(ontology);
      return content.length>0;
    }
    return false;
  }
  
  /**
   * <p>
   *   Tells if has note content for named 
   *   {@link Node}
   * </p>
   * @param name     {@link Node}'s name.
   * @param ontology Name on ontology to check for, if {@code null} checks if
   *                 has content defined over all ontologies.
   * @return {@code true} if has, {@code false} if has not.
   */
  public boolean hasNoteContent(String name, String ontology)
  {
    Node node=getNode(name);
    if (node!=null)
    {
      Content[] content=(ontology==null) ? node.getContent() :
                                           node.getContent(ontology);
      
      for (Content curr : content) if (curr.isNote()) return true;  
    }
    return false;
  }
  
  @Override
  public String toString() 
  {
    CharArrayWriter caw=new CharArrayWriter();
    PrintWriter pw=new PrintWriter(caw);
    
    for (Node curr : m_nodes.values()) pw.print(curr);
    
    pw.flush();
    return caw.toString();
  }

  @Override
  public Iterator<Node> iterator(){ return m_nodes.values().iterator(); }
  
}
